#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include "lv_drivers/display/fbdev.h"
#include "lv_drivers/indev/evdev.h"
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <stdio.h>
#include <string.h>
#include "objj.h"
#include "UI/ui.h"

// 显示缓冲区大小定义
#define DISP_BUF_SIZE (128 * 1024)

// 外部UI元素声明（包含所有按钮和标签）
extern lv_obj_t *ui_Button1;
extern lv_obj_t *ui_Label1;
extern lv_obj_t *ui_Button2;
extern lv_obj_t *ui_Label2;
extern lv_obj_t *ui_Button3;
extern lv_obj_t *ui_Label3;
extern lv_obj_t *ui_Button4;
extern lv_obj_t *ui_Label4;
extern lv_obj_t *ui_Button5;
extern lv_obj_t *ui_Label6;
extern lv_obj_t *ui_Button6;
extern lv_obj_t *ui_Label5;
extern lv_obj_t *ui_Button7;
extern lv_obj_t *ui_Label7;
extern lv_obj_t *ui_Button8;
extern lv_obj_t *ui_Label8;
extern lv_obj_t *ui_Button9;
extern lv_obj_t *ui_Label9;
extern lv_obj_t *ui_Button10;
extern lv_obj_t *ui_Label10;
extern lv_obj_t *ui_Button11;
extern lv_obj_t *ui_Label11;
extern lv_obj_t *ui_Button12;
extern lv_obj_t *ui_Label12;
extern lv_obj_t *ui_Button13;
extern lv_obj_t *ui_Label13;
extern lv_obj_t *ui_Button14;
extern lv_obj_t *ui_Label14;
extern lv_obj_t *ui_Button15;
extern lv_obj_t *ui_Label15;
extern lv_obj_t *ui_Button16;
extern lv_obj_t *ui_Label16;
extern lv_obj_t *ui_Button17;
extern lv_obj_t *ui_Label17;
extern lv_obj_t *ui_Button18;
extern lv_obj_t *ui_Label18;
// 添加Image18和Image11的外部声明
extern lv_obj_t *ui_Image18;
extern lv_obj_t *ui_Image11;
// 添加Image19和Image12的外部声明
extern lv_obj_t *ui_Image19;
extern lv_obj_t *ui_Image12;

/**
 * 终端输入检查定时器回调函数
 * 该函数定期检查终端是否有输入，如果有输入则查找对应的按钮并触发点击事件
 * @param timer 定时器对象
 */
static void input_check_timer(lv_timer_t *timer)
{
    char input[100];
    fd_set readfds;
    struct timeval tv;
    int retval;

    // 初始化文件描述符集合
    FD_ZERO(&readfds);
    FD_SET(STDIN_FILENO, &readfds);

    // 设置超时时间为0，使select立即返回
    tv.tv_sec = 0;
    tv.tv_usec = 0;

    // 检查标准输入是否有数据可读
    retval = select(STDIN_FILENO + 1, &readfds, NULL, NULL, &tv);
    
    if (retval == -1) 
    {
        perror("select() 错误");
        return;
    } 
    else if (retval > 0 && FD_ISSET(STDIN_FILENO, &readfds)) 
    {
        // 从标准输入读取数据
        if (fgets(input, sizeof(input), stdin) != NULL) 
        {
            // 移除换行符和可能的回车符
            input[strcspn(input, "\n\r")] = '\0';
            
            // 按钮映射表（保持与ui.c一致）
            struct {
                lv_obj_t *button;
                lv_obj_t *label;
            } button_map[] = {
                {ui_Button1, ui_Label1},
                {ui_Button2, ui_Label2},
                {ui_Button3, ui_Label3},
                {ui_Button4, ui_Label4},
                {ui_Button5, ui_Label6},
                {ui_Button6, ui_Label5},
                {ui_Button7, ui_Label7},
                {ui_Button8, ui_Label8},
                {ui_Button9, ui_Label9},
                {ui_Button10, ui_Label10},
                {ui_Button11, ui_Label11},
                {ui_Button12, ui_Label12},
                {ui_Button13, ui_Label13},
                {ui_Button14, ui_Label14},
                {ui_Button15, ui_Label15},
                {ui_Button16, ui_Label16},
                {ui_Button17, ui_Label17},
                {ui_Button18, ui_Label18},
                {NULL, NULL}  // 结束标记
            };

            // 查找匹配的按钮并触发点击事件
            for (int i = 0; button_map[i].button != NULL; i++) {
                if (!button_map[i].button || !button_map[i].label) continue;
                
                // LVGL 8.2使用lv_label_get_text获取标签文本
                const char *label_text = lv_label_get_text(button_map[i].label);
                if (label_text && strcmp(input, label_text) == 0) {
                    // 发送点击事件，触发动画
                    lv_event_send(button_map[i].button, LV_EVENT_CLICKED, NULL);
                    printf("已触发按钮 '%s' 的动画\n", input);
                    return;
                }
            }

            printf("未找到文字为 '%s' 的按钮\n", input);
        }
    }
}

/**
 * 显示当前屏幕按钮文字的定时器回调函数
 * 该函数定期在终端显示当前屏幕上的所有按钮功能名称
 * @param timer 定时器对象
 */
static void display_buttons_timer(lv_timer_t *timer)
{
    // 按钮映射表（保持与ui.c一致）
    struct {
        lv_obj_t *button;
        lv_obj_t *label;
    } button_map[] = {
        {ui_Button1, ui_Label1},
        {ui_Button2, ui_Label2},
        {ui_Button3, ui_Label3},
        {ui_Button4, ui_Label4},
        {ui_Button5, ui_Label6},
        {ui_Button6, ui_Label5},
        {ui_Button7, ui_Label7},
        {ui_Button8, ui_Label8},
        {ui_Button9, ui_Label9},
        {ui_Button10, ui_Label10},
        {ui_Button11, ui_Label11},
        {ui_Button12, ui_Label12},
        {ui_Button13, ui_Label13},
        {ui_Button14, ui_Label14},
        {ui_Button15, ui_Label15},
        {ui_Button16, ui_Label16},
        {ui_Button17, ui_Label17},
        {ui_Button18, ui_Label18},
        {NULL, NULL}  // 结束标记
    };

    printf("\n当前屏幕支持的功能:\n");
    // 获取当前活动屏幕
    lv_obj_t *current_screen = lv_scr_act();
    
    // 遍历所有按钮，检查是否在当前屏幕上
    for (int i = 0; button_map[i].button != NULL; i++) {
        if (!button_map[i].button || !button_map[i].label) continue;
        
        // 检查按钮是否在当前屏幕上
        lv_obj_t *btn_parent = button_map[i].button;
        while (btn_parent) {
            if (btn_parent == current_screen) {
                // 按钮在当前屏幕上，显示其标签文字
                const char *label_text = lv_label_get_text(button_map[i].label);
                if (label_text) {
                    printf("- %s\n", label_text);
                }
                break;
            }
            btn_parent = lv_obj_get_parent(btn_parent);
        }
    }
    printf("\n");
}

/**
 * Image18角度监控定时器回调函数
 * 该函数定期检查Image18的角度，并根据角度值设置Image11的透明度
 * @param timer 定时器对象
 */
static void image18_angle_monitor_timer(lv_timer_t *timer)
{
    // 获取Image18的角度值(单位是0.1度)
    int angle = lv_img_get_angle(ui_Image18);
    
    // 判断角度是否大于95度(950分)
    if (angle > 950) 
    {
        // 设置Image11的不透明度为255（完全不透明）
        lv_obj_set_style_opa(ui_Image11, 255, 0);
    } else {
        // 设置Image11的不透明度为100（半透明）
        lv_obj_set_style_opa(ui_Image11, 100, 0);
    }
}

/**
 * Image19角度监控定时器回调函数
 * 该函数定期检查Image19的角度，并根据角度值设置Image12的透明度
 * @param timer 定时器对象
 */
static void image19_angle_monitor_timer(lv_timer_t *timer)
{
    // 获取Image19的角度值(单位是0.1度)
    int angle = lv_img_get_angle(ui_Image19);
    
    // 判断角度是否大于200度(2000分)
    if (angle > 2000) 
    {
        // 设置Image12的不透明度为255（完全不透明）
        lv_obj_set_style_opa(ui_Image12, 255, 0);
    } else {
        // 设置Image12的不透明度为100（半透明）
        lv_obj_set_style_opa(ui_Image12, 100, 0);
    }
}

/**
 * LVGL 8.2时钟源实现
 * 提供LVGL库所需的系统时间戳（毫秒）
 * @return 当前系统启动以来的毫秒数
 */
uint32_t lv_tick_get(void)
{
    static uint64_t start_ms = 0;
    if (start_ms == 0) {
        struct timeval tv_start;
        gettimeofday(&tv_start, NULL);
        start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;
    }

    struct timeval tv_now;
    gettimeofday(&tv_now, NULL);
    uint64_t now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;

    return now_ms - start_ms;
}

/**
 * 主函数 - 程序入口点
 * 初始化LVGL图形库、显示设备、输入设备和用户界面
 * 创建各种定时器来处理输入、显示和监控任务
 * 进入主循环处理图形界面事件
 */
int main(void)
{
    // 初始化LVGL图形库
    lv_init();

    // 初始化显示设备（帧缓冲设备）
    fbdev_init();

    // 配置显示缓冲区
    static lv_color_t buf[DISP_BUF_SIZE];
    static lv_disp_draw_buf_t disp_buf;
    lv_disp_draw_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE);

    // 配置显示驱动
    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.draw_buf   = &disp_buf;
    disp_drv.flush_cb   = fbdev_flush;
    disp_drv.hor_res    = 800;    // 根据实际屏幕分辨率调整
    disp_drv.ver_res    = 480;    // 根据实际屏幕分辨率调整
    lv_disp_drv_register(&disp_drv);

    // 初始化输入设备
    evdev_init();
    static lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = evdev_read;
    lv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv);

    // 配置鼠标光标（如果需要）
    LV_IMG_DECLARE(mouse_cursor_icon);    // 确保该图标已定义
    lv_obj_t *cursor_obj = lv_img_create(lv_scr_act());
    lv_img_set_src(cursor_obj, &mouse_cursor_icon);
    lv_indev_set_cursor(mouse_indev, cursor_obj);

    // 初始化UI界面
    ui_init();

    // 创建输入检查定时器（每100ms检查一次终端输入）
    lv_timer_create(input_check_timer, 100, NULL);
    
    // 创建显示按钮文字的定时器（每15秒显示一次）
    lv_timer_create(display_buttons_timer, 15000, NULL);
    
    // 创建Image18角度监控定时器（每100ms检查一次）
    lv_timer_create(image18_angle_monitor_timer, 100, NULL);
    
    // 创建Image19角度监控定时器（每100ms检查一次）
    lv_timer_create(image19_angle_monitor_timer, 100, NULL);
    
    printf("UI初始化完成,可在终端输入功能名字\n");
    printf("每15秒将显示当前屏幕支持的功能\n");

    // 主循环
    while (1) {
        lv_timer_handler();    // 处理LVGL任务
        usleep(5000);          // 5ms延迟，降低CPU占用
    }

    return 0;
}